package com.levi.aop;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.levi.cache.UserCache;
import com.levi.common.AjaxResult;
import com.levi.domain.User;
import com.levi.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;

/**
 * @author shentong
 * @since 2022/3/11 8:29 PM 环绕通知实现修改用户信息之后更新用户缓存信息
 */
@Aspect
@Slf4j
@Component
public class UserAop {

	@Autowired
	private UserService userService;

	public UserAop() {
		log.info("初始化用户管理拦截器");
	}

	@Pointcut("execution(* com.levi.controller.UserController.*(..))")
	public void pointCutMethod() {
		log.info("定义切点");
	}

	@Around("pointCutMethod()")
	public Object doAround(ProceedingJoinPoint pjp) throws Throwable {

		log.info("执行环绕切面 ");

		String method = pjp.getSignature().getName();

		if ("add".equals(method) || "edit".equals(method)) {
			Signature signature = pjp.getSignature();
			MethodSignature methodSignature = (MethodSignature) signature;
			String[] parameterNames = methodSignature.getParameterNames();
			JsonObject jsonObject = getJson(parameterNames, pjp.getArgs());
			String username = jsonObject.get("user").getAsJsonObject().get("name").getAsString();

			AjaxResult args = (AjaxResult) pjp.proceed();
			if (args.getCode().equals(HttpStatus.OK.value())) {
				EntityWrapper<User> ew = new EntityWrapper<>();
				ew.eq("c_username", username);
				User user = userService.selectOne(ew);
				UserCache.updateUserCache(user);
			}
			return args;
		}
		else {
			return pjp.proceed();
		}
	}

	/**
	 * 提取参数名及参数值的JSON描述。
	 * @param parameterNames
	 * @param args
	 * @return
	 */
	private JsonObject getJson(String[] parameterNames, Object[] args) {
		Gson json = new Gson();
		JsonObject jsonObject = new JsonObject();
		for (int x = 0; x < parameterNames.length; x++) {
			String key = parameterNames[x];
			Object obj = args[x];
			if (obj == null) {
				jsonObject.addProperty(key, "");
			}
			else {
				jsonObject.add(key, json.toJsonTree(obj));
			}
		}
		return jsonObject;
	}

}
